﻿#pragma once
#ifndef _BYTE_ARRAY_
#define _BYTE_ARRAY_
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;


const unsigned int MAXMSGSIZE = 16 * 1024;                    // 32K  单个网络消息最大长度,(超过极易导致物理服务器收发队列阻塞)
const unsigned int INCRSIZE = 32 * 1024;                    // 2K  每次增量

#define BYTE_DELETE_ARRAY( ptr )if (ptr != NULL){delete[] ptr;ptr = NULL;}

//java服务器高底位转换
template<size_t T> void inline convertToByte(unsigned char* val)
{
	std::swap(*val, *(val + T - 1));
	convertToByte<T - 2>(val + 1);
}

template<> void inline convertToByte<0>(unsigned char*val){}
template<> void inline convertToByte<1>(unsigned char*val){}

template<typename T> void inline convertToByteStream(T& val)
{
	convertToByte<sizeof(T)>((unsigned char*)(&val));
}

class  ByteArray 
{
public:
	ByteArray(unsigned int mBufferSize = MAXMSGSIZE);
	ByteArray(const char* pszFileName, const char* pszMode);
	ByteArray(const char* pszFileName, const char* pszFileNameCopy, const char* pszMode, bool local);
	virtual ~ByteArray();

	void print();
	void resize(unsigned int mLength);
	void reuse(){ m_nRdptr = 0; m_nWrPtr = 0; m_nTotalSize = MAXMSGSIZE; }
public:
	int	read_int();									// 从字节流读取32位整形
	unsigned int read_uint();						// 从字节流读取32位整形

	long long read_int64();							// 从字节流读取64位整形
	unsigned long long read_uint64();				// 从字节流读取64位无符号整形
	short read_int16();								// 从字节流读取16位整形
	unsigned short read_uint16();      // 从字节流读取16位无符号整形

	short read_short();								// 从字节流读取短整形
	unsigned short read_ushort();					// 从字节流读取无符号短整形

	long read_long();								// 从字节流读取长整形
	unsigned long read_ulong();						// 从字节流读取无符号长整形

	signed char           read_char();				// 从字节流读取字符
	signed char           read_byte();				// 从字节流读取字符
	unsigned char  read_uchar();					// 从字节流读取无符号字符整数

	bool           read_bool();                     // 从字节流读取Bool值

	float          read_float();                    // 从字节流读取浮点数
	double         read_double();                   // 从字节流读取双精度数

	char *         read_string(char* info, unsigned int len); // 从字节流读取字符串
	std::string    read_string();                   // 从字节流读取字符串
	std::string    read_wstring();                  // 从字节流读取Unicode字符串,并转化为UTF8

	void *         read_stream(int &mLength);//往字节流读出数据
	void           write_stream(void * mChars, int mLength);//向字节流写入数据

	void 		   write_int(int);                   // 向字节流写32位整形
	void 		   write_uint(unsigned int);        // 向字节流写32位无符号整形

	void 		   write_int64(long long);           // 向字节流写64位整形
	void 		   write_uint64(unsigned long long); // 向字节流写64位无符号整形


	void 		   write_int16(short);              // 向字节流写16位整形
	void 		   write_uint16(unsigned short);              // 向字节流写16位无符号整形

	void 		   write_short(short);               // 向字节流写短整
	void 		   write_ushort(unsigned short);     // 向字节流写无符号短整

	void 		   write_long(long);                  // 向字节流写长整
	void 		   write_ulong(unsigned long);        // 向字节流写无符号长整

	void 		   write_char(signed char);           // 向字节流写字符型
	void 		   write_byte(signed char);           // 向字节流写字符型
	void 		   write_uchar(unsigned char);        // 向字节流写无符号字符型整数

	void 		   write_bool(bool);                  // 向字节流写布尔型

	void 		   write_float(float);                 // 向字节流写浮点数
	void 		   write_double(double);              // 向字节流写双精度数

	void 		   write_string(const char* str);       // 向字节流写字符串
	void 		   write_string(const std::string& str); // 向字节流写字符串
	void 		   write_wstring(const std::string& str); // 向字节流写unicode字符串

	void          write_chars(const char* str);     //写入字节流

public:
	int 		   length() const;                   //字节流当前长度

	///// add by vincent 20101218 /////////
	void setTag(int t){ tag = t; }
	long  getTag(){ return tag; }
	void setCmdType(unsigned short _t){ cmdType = _t; }
	unsigned short getCmdType(){ return cmdType; }
	////////add end ///////////////

public:
	char*          base() const;                      //字节流内部实现
	char*          end(void) const;
	char*          rd_ptr(void) const;
	char*          wr_ptr(void);
	void           rd_ptr(int n);
	void           wr_ptr(int n);
	unsigned int   space();
	int            copy(const char *buf, int n);
	void		   rd_skip(int mBytes); //skip read bytes

private:
	///// add by vincent 20101218 /////////
	int tag;
	short cmdType;
	////////add end ///////////////

private:
	//    void * memcpy(void * dst, void const * src, size_t len)
	//    {
	//        char * pDst = (char *) dst;
	//        char const * pSrc = (char const *) src;
	//        
	//        while (len--)
	//        {
	//            *pDst++ = *pSrc++;
	//        }
	//        
	//        return (dst);
	//    }

	void *memcpy(void *dst, const void *src, size_t count)
	{
		char *p_dst = (char*)(dst);
		char *p_src = (char*)(src);
		unsigned int i;
		if (dst>src && (char*)dst <= ((char*)src + count - 1))//如果p_dst=p_src那直接拷贝就可以了，
		{                                            //如果p_dst=p_src+count-1,说明还有一个重叠，
			while (count)
			{
				*(p_dst + count - 1) = *(p_src + count - 1);
				count--;
			}
		}
		else
		{
			for (i = 0; i<count; i++)
				*(p_dst + i) = *(p_src + i);
		}
		return dst;
	}

	template<typename T> friend ByteArray& operator>>(ByteArray& msg, T& v)      //运算符重载
	{
		msg.Read(&v);
		return msg;
	}

	friend ByteArray& operator>>(ByteArray& msg, std::string& str)
	{
		str = msg.read_string();
		return msg;
	}

	template<typename T> friend ByteArray& operator<<(ByteArray& msg, const T& v)
	{
		msg.Write(v);
		return msg;
	}

	friend ByteArray& operator<<(ByteArray& msg, const std::string& str)
	{
		msg.write_string(str);
		return msg;
	}


	// 	template<size_t T> void convert(unsigned char* val)
	// 	{
	// 		std::swap(*val,*(val+T-1));
	// 		convert<T-2>(val+1);
	// 	}
	// 
	// 	template<> void convert<0>(unsigned char*val){}
	// 	template<> void convert<1>(unsigned char*val){}
	// 
	// 	template<typename T> void apply(T& val)
	// 	{
	// 		convert<sizeof(T)>((unsigned char*)(&val));
	// 	}

	template<typename T>
	T& Read(T* pVar, bool readonly = false)
	{
		*pVar = *((T*)rd_ptr());
		if (!readonly)//添加只读，不移指针支持，为了调试，Mike
			rd_ptr(sizeof(T));
		return *pVar;
	}

	template<typename T>
	void Write(const T& value)
	{
		//CCLOG("Write value :%ld",value);
		T* pV = (T*)wr_ptr();
		*pV = value;
		wr_ptr(sizeof(T));
	}

private:
	char* m_pContent;                               //字节流内容指针
	unsigned int  m_nTotalSize;                     //字节流允许大小
	int   m_nRdptr;                                 //读取位置
	int   m_nWrPtr;                                 //写入位置

private:
	unsigned char* getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize);
};



//////////////////////add by vincent 20101218/////////////
/*PacketByteArray interface*/
class PacketByteArray
{
public:
	virtual void serialize(ByteArray *byteArray){};
	virtual void deserialize(ByteArray *byteArray){};
};
///////////////////////add end//////////////////////
#endif